# 装饰器 通过装饰器给函数增加功能但是不改变调用方式和源代码
# 无参装饰器
from functools import wraps  # 导入装饰器wraps功能


def deco(func):  # 装饰器
    @wraps(func)  # 将原函数func的属性完全复制给装饰后的函数 ，实现完全伪装
    def wrapper(*args, **kwargs):
        print("新功能1")
        res = func(*args, **kwargs)
        print("新功能2")
        return res  # 将func的返回值返回

    # 手动将原函数func的属性完全赋值给装饰后的函数
    # wrapper.__name__ = func.__name__
    # wrapper.__doc__ = func.__doc__
    return wrapper


@deco  # @装饰器名称 语法糖实现  index=outer(index) 省略了步骤，让装饰后的函数调用方式一模一样
def index(*args, **kwargs):
    print("这是首页")
    return 1


a = index()
print(a)
print(index.__name__)


# 有参装饰器
def auth(db_type):  # 通过在再包一层实现参数传入
    def deco(func):
        def wrapper(*args, **kwargs):
            print("基于 %s 登录" % db_type)
            res = func(*args, **kwargs)
            return res

        return wrapper

    return deco


# @语法糖  先执行 @auth得到 deco
# login_from_mysql=auth(db_type=mysql) => login_from_mysql=deco
# login_from_mysql=deco(login_from_mysql) => login_from_mysql=wrapper
@auth(db_type="mysql")
def login_from_mysql(*args, **kwargs):
    print("登录成功")
    return 1


@auth(db_type="sqlserver")
def login_from_sqlserver(*args, **kwargs):
    print("登录成功")
    return 1
